﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace UI.TileEngine
{
    public class Tileset
    {

        public enum NeighboorOrientationIndex
        {
            None,
            NoneTR,
            NoneBR,
            NoneBL,
            NoneTL,
            NoneTRBR,
            NoneTRBL,
            NoneTRTL,
            NoneBRBL,
            NoneBRTL,
            NoneBLTL,
            NoneTRBRBL,
            NoneTRBRTL,
            NoneTRBLTL,
            NoneBRBLTL,
            NoneTRBRBLTL,
            Top,
            TopBR,
            TopBL,
            TopBRBL,
            Right,
            RightBL,
            RightTL,
            RightBLTL,
            Bottom,
            BottomTR,
            BottomTL,
            BottomTRTL,
            Left,
            LeftTR,
            LeftBR,
            LeftTRBR,
            TopRight,
            TopRightBL,
            TopBottom,
            TopLeft,
            TopLeftBR,
            RightBottom,
            RightBottomTL,
            RightLeft,
            BottomLeft,
            BottomLeftTR,
            TopRightBottom,
            TopRightLeft,
            TopBottomLeft,
            RightBottomLeft,
            All
        }

        private Point _TileSize;
        private Texture2D _Texture;

        /// <summary>
        /// Builds a tileset from a texture that is composed of tiles
        /// </summary>
        /// <param name="Texture">Texture to apply to this tileset</param>
        /// <param name="TileSize">Size of each tile in the tileset</param>
        public Tileset(Texture2D Texture, Point TileSize)
        {
            this._Texture = Texture;
            this._TileSize = TileSize;
        }

        /// <summary>
        /// Returns the texture for this tileset
        /// </summary>
        public Texture2D Texture
        {
            get
            {
                return this._Texture;
            }
        }

        /// <summary>
        /// Returns the size of each tile in this tileset
        /// </summary>
        public Point TileSize
        {
            get
            {
                return this._TileSize;
            }
        }

        /// <summary>
        /// Returns the computed count of tiles in this tileset texture based on the tilesize
        /// </summary>
        public Point TilesCount
        {
            get
            {
                return new Point(this._Texture.Width / _TileSize.X, this._Texture.Height / _TileSize.Y);
            }
        }

        /// <summary>
        /// Returns the point in tileset which corresponds to the tileindex
        /// </summary>
        /// <param name="TileIndex">Index of the tile based on tileset texture from left to right and up to down</param>
        /// <returns></returns>
        public Point IndexToTile(Int16 TileIndex){
            return new Point((int)TileIndex % this.TilesCount.X, (int)Math.Floor((double)TileIndex / TilesCount.X));
        }

        /// <summary>
        /// Returns the rectangle that matches the tile pointed at
        /// </summary>
        /// <param name="Tile">Tile to draw</param>
        public Rectangle TileToRect(Point Tile)
        {
            return new Rectangle(Tile.X * _TileSize.X, Tile.Y * _TileSize.Y, _TileSize.X, _TileSize.Y);
        }

        /// <summary>
        /// Creates tiles in a layer based on the rectangle specified, each tile will be drawn according to it's neigbhoors
        /// </summary>
        /// <param name="position">Rectangle specifying what tiles to set this tileset to, all neighboors of these matching tiles are checked</param>
        /// <param name="layer">Layer to affect with this tileset</param>
        public void SetTiles(Rectangle position, TileLayer layer)
        {
            for (int y = position.Y; y <= position.Height + position.Y; y++)
            {
                for (int x = position.X; x <= position.Width + position.X; x++)
                {
                    layer.setTile(new Point(x, y), new Tile(layer, this, new Point(x, y)));
                }
            }
        }

    }
}
